package com.zy.datareceiver.binsess.decode.service;

import com.zy.datareceiver.binsess.monitoring.mapper.MonitoringPointMapper;
import com.zy.datareceiver.binsess.rabbit.entity.PassagewayDomain;
import com.zy.datareceiver.binsess.rabbit.entity.ReceiveDataStorage;
import com.zy.datareceiver.binsess.status.mapper.ObjectMonitoringMapper;
import com.zy.datareceiver.binsess.status.mapper.PassagewayMapper;
import com.zy.datareceiver.core.cast.ConCast;
import com.zy.datareceiver.core.common.SpringApplicationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 对象监测线程
 * */
public class ObjectStatusMonitoring extends Thread {
    private static final Logger log = LoggerFactory.getLogger(ObjectStatusMonitoring.class);

    @Value("${status.split.time}")
    public static final long timeout= 1000 * 60 * 11;//十二分钟没有数据，则认为设备全部断开

    private PassagewayMapper passagewayMapper = SpringApplicationContext.getBean(PassagewayMapper.class);
    private ObjectMonitoringMapper objectMonitoringMapper = SpringApplicationContext.getBean(ObjectMonitoringMapper.class);
    private MonitoringPointMapper monitoringPointMapper = SpringApplicationContext.getBean(MonitoringPointMapper.class);

    @Override
    public void run() {
        try {
            HashMap<String,Long> statusMap = new HashMap<>();
            statusMap.put(ConCast.SenderType.ACCESS,System.currentTimeMillis());
            statusMap.put(ConCast.SenderType.HTTP,System.currentTimeMillis());
            statusMap.put(ConCast.SenderType.SOCKET,System.currentTimeMillis());
            long now = System.currentTimeMillis();
            while (true) {
                PassagewayDomain passagewayDomain = ReceiveDataStorage.getInstance().statusQueue.poll(11, TimeUnit.MINUTES);
                if (passagewayDomain == null) {
                    Iterator<Map.Entry<String, Long>> iterator = statusMap.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry<String, Long> entity = iterator.next();
                        if (now - entity.getValue() > timeout) {
                            disConnection(entity.getKey());
                            now = System.currentTimeMillis();
                        }
                    }
                } else {
                    String senderType = passagewayDomain.getType();
                    long preTime = statusMap.get(senderType);
                    if (now - preTime > timeout) { //项目已经重启
                        recoverConnection(senderType);
                        now = System.currentTimeMillis();
                    }
                }
            }
        } catch (Exception e) {

        }
    }


    private Integer getSenderTypeIdByKey(String key){
        switch (key){
            case ConCast
                    .SenderType
                    .ACCESS:
                return 0;
            case ConCast
                    .SenderType
                    .HTTP:
                return 1;
            case ConCast
                    .SenderType
                    .SOCKET:
                return 2;
            default:
                return -1;
        }
    }

    //断开连接，key可选类型SOCKET HTTP ACCESS
    @Transactional
    public void disConnection(String key) {
        Integer sendTypeId = getSenderTypeIdByKey(key);

        passagewayMapper.updateDisConnectionByType(sendTypeId);
        objectMonitoringMapper.updateDisConnectionByType(key);
        monitoringPointMapper.updateDisConnectionByType(sendTypeId);
    }


    @Transactional
    public void recoverConnection(String key) {
        Integer sendTypeId = getSenderTypeIdByKey(key);
        passagewayMapper.updateRecoverConnectionByType(sendTypeId);
        objectMonitoringMapper.updateRecoverConnectionByType(key);
        monitoringPointMapper.updateRecoverConnectionByType(sendTypeId);
    }
}
